from cmdb import models
from cmdb import common
import os
import yaml
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
from kubernetes.client.rest import ApiException
from kubernetes import client, config
import urllib3
class Web:
    def __init__(self,project,name,domain,namespace):
        self.project=project
        self.name=name
        self.domain=domain
        self.namespace=namespace
        self.csh()
    def csh(self):
        res=models.Namespace.objects.filter(name=self.namespace)
        self.nas=res[0].nas
        self.phpsvcip=common.svc_ip(self.namespace,1)
    # 创建存储和存储申明
    def nas_pv_sm(self):
        www_data = '''apiVersion: v1
kind: PersistentVolume
metadata:
  name: {0}-www
spec:
  capacity:
    storage: 1Gi
  storageClassName: nas
  accessModes:
    - ReadWriteMany
  flexVolume:
    driver: "alicloud/nas"
    options:
      mode: '555'
      modeType: recursive
      server: "{1}"
      path: "/{0}/www/"
      vers: "3"
      options: "nolock,tcp,noresvport"
'''.format(self.project, self.nas)
        logs_data = '''apiVersion: v1
kind: PersistentVolume
metadata:
  name: {0}-logs
spec:
  capacity:
    storage: 1Gi
  storageClassName: nas
  accessModes:
    - ReadWriteMany
  flexVolume:
    driver: "alicloud/nas"
    options:
      mode: '755'
      modeType: recursive
      server: "{1}"
      path: "/{0}/logs/"
      vers: "3"
      options: "nolock,tcp,noresvport" '''.format(self.project, self.nas)
        www_sm = '''apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: 'yes'
    pv.kubernetes.io/bound-by-controller: 'yes'
  finalizers:
    - kubernetes.io/pvc-protection
  name: {0}-www
  namespace: {1}
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      alicloud-pvname: {0}-www
  storageClassName: nas
  volumeMode: Filesystem
  volumeName: {0}-www        
'''.format(self.project, self.namespace)
        logs_sm = '''
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: 'yes'
    pv.kubernetes.io/bound-by-controller: 'yes'
  finalizers:
    - kubernetes.io/pvc-protection
  name: {0}-logs
  namespace: {1}
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      alicloud-pvname: {0}-logs
  storageClassName: nas
  volumeMode: Filesystem
  volumeName: {0}-logs
'''.format(self.project, self.namespace)
        with open(BASE_DIR+"/data/www-pv.yaml", "w", encoding="utf8") as f1:
            f1.write(www_data)
        with open(BASE_DIR+"/data/logs-pv.yaml", "w", encoding="utf8") as f2:
            f2.write(logs_data)
        with open(BASE_DIR+"/data/www-sm.yaml", "w", encoding="utf8") as f3:
            f3.write(www_sm)
        with open(BASE_DIR+"/data/logs-sm.yaml", "w", encoding="utf8") as f4:
            f4.write(logs_sm)

    # 创建nginx配置
    def openresty_config(self):
        config_data ='''         server {\n        listen       80;\n        server_name  %s;\n        charset utf-8;\n        root   /data/www/%s/public;\n        index  index.php  index.html index.htm;\n        location / {\n        if (!-e $request_filename){\n            rewrite ^/(.*)$ /index.php?s=/$1 last;\n        }\n        }\n        #error_page  404              /404.html;\n\n        # redirect server error pages to the static page /50x.html\n        #\n        error_page   500 502 503 504  /50x.html;\n        location = /50x.html {\n            root   html;\n        }\n       location ~ \\.php(.*)$ {\n        root   /data/www/%s/public;\n        fastcgi_pass    %s:9000;\n        fastcgi_index  index.php;\n        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;\n        #path_info\n        fastcgi_buffer_size 128k;\n        fastcgi_buffers 32 32k;\n        set $path_info \"\";\n        set $real_script_name $fastcgi_script_name;\n        if ($fastcgi_script_name ~ \"^(.+\\.php)(/.+)$\") {\n            set $real_script_name $1;\n            set $path_info $2;\n        }\n        fastcgi_param SCRIPT_NAME $real_script_name;\n        fastcgi_param PATH_INFO $path_info;\n        include        fastcgi_params;\n\n       }\n        location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$\n        {\n                expires 3d;\n        }\n\n        location ~ .*\\.(js|css)?$\n        {\n                expires 3d;\n        }\n\t    access_log /data/logs/nginx/%s.access.log main;\n}
''' % (self.domain,self.name,self.name,self.phpsvcip,self.domain)
        with open("data/openresty-config.conf", "w", encoding="utf8") as f:
            f.write(config_data)
    # 创建php
    def php(self):
        php_data = '''apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: '6'
  labels:
    app: {0}
  name: {0}-php
  namespace: {1}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: {0}-php
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: {0}-php
    spec:
      containers:
        - env:
            - name: TIME_ZOME
              value: Asia/Shanghai
          image: 'registry-vpc.cn-shenzhen.aliyuncs.com/kbitweb/php7.2.16:2.0.1'
          imagePullPolicy: Always
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 15
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 9000
            timeoutSeconds: 1
          name: {0}-php
          ports:
            - containerPort: 9000
              name: php
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            initialDelaySeconds: 15
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 9000
            timeoutSeconds: 1
          resources:
            limits:
              cpu: '2'
              memory: 2Gi
            requests:
              cpu: 100m
              memory: 100Mi
          volumeMounts:
            - mountPath: /data/logs
              name: {0}-logs
            - mountPath: /data/www/
              name: {0}-www 
      dnsPolicy: ClusterFirst
      imagePullSecrets:
        - name: kmrb-secret
      restartPolicy: Always
      schedulerName: default-scheduler
      volumes:
        - name: {0}-logs
          persistentVolumeClaim:
            claimName: {0}-logs
        - name: {0}-www
          persistentVolumeClaim:
            claimName: {0}-www
'''.format(self.project, self.namespace)
        php_svc = '''apiVersion: v1
kind: Service
metadata:
  name: {0}-php-svc
  namespace: {2}
spec:
  clusterIP: {1}
  ports:
    - name: php
      port: 9000
      protocol: TCP
      targetPort: 9000
  selector:
    app: {0}-php
  sessionAffinity: None
  type: ClusterIP
'''.format(self.project, self.phpsvcip, self.namespace)
        with open("data/php.yaml", "w", encoding="utf8") as f1:
            f1.write(php_data)
        with open("data/php-svc.yaml", "w", encoding="utf8") as f2:
            f2.write(php_svc)

    # 创建openresty
    def openresty(self):
        op_data = '''apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: '5'
  labels:
    app: {0}
  name: {0}-openresty
  namespace: {2}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: {0}-openresty
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: {0}-openresty
    spec:
      containers:
        - env:
            - name: TIME_ZOME
              value: Asia/Shanghai
          image: registry-vpc.cn-shenzhen.aliyuncs.com/kbitweb/kbitopenresty1.15:1.0.4
          imagePullPolicy: Always
          name: {0}-openresty
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 15
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 80
            timeoutSeconds: 1
          name: {0}
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            initialDelaySeconds: 15
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 80
            timeoutSeconds: 1
          resources:
            limits:
              cpu: '2'
              memory: 1Gi
            requests:
              cpu: 100m
              memory: 100Mi
          volumeMounts:
            - mountPath: /data/www/
              name: volume-{0}-www          
            - mountPath: /data/logs/
              name: volume-{0}-logs
            - mountPath: /etc/localtime
              name: volume-localtime         
            - mountPath: /opt/openresty/nginx/conf/vhost
              name: volume-{0}-config 

      dnsPolicy: ClusterFirst
      imagePullSecrets:
        - name: kmrb-secret
      restartPolicy: Always
      schedulerName: default-scheduler
      volumes:     
        - name: volume-{0}-www
          persistentVolumeClaim:
            claimName: {0}-www      
        - name: volume-{0}-logs
          persistentVolumeClaim:
            claimName: {0}-logs 
        - hostPath:
            path: /etc/localtime
            type: ''
          name: volume-localtime
        - configMap:
            defaultMode: 420
            name: {1}.conf
          name: volume-{0}-config
'''.format(self.project, self.domain, self.namespace)
        op_svc_data = '''apiVersion: v1
kind: Service
metadata:
  name: {0}-openresty-svc
  namespace: {1}
spec:
  clusterIP: None
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: {0}-openresty
  sessionAffinity: None
  type: ClusterIP
'''.format(self.project, self.namespace)
        with open("data/openresty.yaml", "w", encoding="utf8") as f:
            f.write(op_data)
        with open("data/openresty-svc.yaml", "w", encoding="utf8") as f:
            f.write(op_svc_data)

    # 创建ingress
    def ingress(self):
        ig_data = '''
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/service-weight: ''
  generation: 4
  name: {0}
  namespace: {2}
spec:
  rules:
    - host: {0}
      http:
        paths:
          - backend:
              serviceName: {1}-openresty-svc
              servicePort: 80
            path: /        
'''.format(self.domain, self.project, self.namespace)
        with open("data/ingress.yaml", "w", encoding="utf8") as f:
            f.write(ig_data)

    @staticmethod
    def get_web(domain):
        res=models.Web.objects.filter(domain=domain)
        data=dict()
        data["project"]=res.project
        data["name"]=res.project
        data["nas"]=res.namespace.nas
        data["namespace"]=res.namespace.name
        return data

class K8s:
    def __init__(self,name):
        self.name =name
        self.get_all()

    def get_all(self):
        obj=models.Cluster.objects.get(name=self.name)
        self.config=os.path.join(BASE_DIR,"config",obj.config)

    def get_namespace(self):
        data = []
        try:
            namespaces=os.popen("kubectl --kubeconfig {} get namespace|awk  '{print$1}'|grep -v STATUS".format(self.config))
            data=namespaces.split('\n')
        except ApiException as e:
            print("Exception list_namespace: %s\n" % e)
        return  data

    def get_service(self,namespace):
        data = []
        try:
             svcs = os.popen("kubectl --kubeconfig {}  get svc -n {}|grep -v AGE|awk  '{print$1,$3}'".format(self.config,namespace))
             data=svcs.split('\n')
        except ApiException as e:
            print("Exception list_service: %s\n" % e)
        return data

    def add_www_pv_sm(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","www-pv.yaml"),namespace))
        res_sm=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","www-sm.yaml"),namespace))

    def add_logs_pv_sm(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","logs-pv.yaml"),namespace))
        res_sm=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","logs-sm.yaml"),namespace))

    def add_openresty_config(self,namespace,domain):
        res=os.popen("kubectl --kubeconfig {}  create configmap {}.conf  --from-file={} --namespace={}".format(self.config,domain,os.path.join(BASE_DIR,"data","openresty-config.conf"),namespace))

    def add_openresty(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","openresty.yaml"),namespace))
    def add_php(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","php.yaml"),namespace))
    def add_openresty_svc(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","openresty-svc.yaml"),namespace))
    def add_php_svc(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","php-svc.yaml"),namespace))

    def add_ingress(self,namespace):
        res=os.popen("kubectl --kubeconfig {}  create -f {} -n {}".format(self.config,os.path.join(BASE_DIR,"data","ingress.yaml"),namespace))

    def get_job(self):
            #获取job
            jobs=os.popen("kubectl --kubeconfig {}   get  jobs    --all-namespaces|grep -v NAME".format(self.config)).read()
            b=list()
            for i in jobs.split('\n'):
                if i:
                    l = i.split(' ')
                    while '' in l :
                        l.remove('')
                    b.append(l[1])
            job = list()
            joball = list()
            for i in b:
                if "tekton" not in i:
                    job.append(i[:-11])
                    joball.append(i)
            podname = set(job)
            return (podname,b)

import openpyxl

class ReadExcel(object): #读取excel数据的类
    def __init__(self,file_name,sheet_name):
        """
        这个是用来初始化读取对象的
        :param file_name: 文件名 ---> str类型
        :param sheet_name: 表单名 ———> str类型
        """
        # 打开文件
        self.wb = openpyxl.load_workbook(file_name)
        # 选择表单
        self.sh = self.wb[sheet_name]
    def read_data_line(self):
        #按行读取数据转化为列表
        rows_data = list(self.sh.rows)
        # 获取表单的表头信息
        titles = []
        for title in rows_data[0]:
            titles.append(title.value)
        #定义一个空列表用来存储测试用例
        cases = []
        for case in rows_data[1:]:
            data = []
            case_data=None
            for cell in case: #获取一条测试用例数据
                data.append(cell.value)
                case_data = dict(list(zip(titles,data)))
            cases.append(case_data)
        return cases